﻿using FlyingCircusWebIS.Controllers.Utilidades;
using FlyingCircusWebIS.Models;
using FlyingCircusWebIS.ViewModels.CidadeVM;
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace FlyingCircusWebIS.Controllers
{
    public class CidadeController : Controller
    {

        // Identificador das actions disponíveis no controller
        public const string INDEX_ACTION = "Index";
        public const string FORM_ACTION = "Form";
        public const string DESATIVAR_ACTION = "Desativar";
        public const string ATIVAR_ACTION = "Ativar";


        // Retorna a página mestre do "cadastro" de cidades
        public ActionResult Index()
        {
            CidadeIndexVM vm = ConstruirIndexVM();
            return View(vm);
        }


        // Retorna os dados para a view (edição ou novo)
        public ActionResult Form(int? id)
        {
            CidadeFormVM vm;
            if (id.HasValue)
            {
                vm = ConstruirFormVMParaEdicao(id.Value);
                if (vm == null)
                    return new HttpNotFoundResult();
            }
            else
            {
                vm = ConstruirFormVMParaNovo();
            }

            return View(vm);
        }



        // Recebe os dados via POST da view
        [HttpPost]
        public ActionResult Form(CidadeFormVM vm)
        {
            Cidade registro = ConverterFormVM(vm);

            if (ModelState.IsValid)
            {
                if (vm.Edicao)
                    AtualizarRegistro(registro);
                else
                    InserirRegistro(registro);

                return RedirectToAction(INDEX_ACTION);
            }
            else
            {
                return View(vm);
            }
        }


        // Recebe a requisição de desativar um registro
        public JsonResult Desativar(int id)
        {
            DesativarRegistroPorId(id);
            return Json(new JsonActionResultModel("Registro desativado com sucesso."));
        }

        // Recebe a requisição de ativar um registro
        public JsonResult Ativar(int id)
        {
            AtivarRegistroPorId(id);
            return Json(new JsonActionResultModel("Registro ativado com sucesso."));
        }



        // -----------------------------------------------------------------------------------------
        // Métodos auxiliares 
        // -----------------------------------------------------------------------------------------

        private CidadeIndexVM ConstruirIndexVM()
        {
            CidadeIndexVM vm = new CidadeIndexVM();

            List<Cidade> registros = ListarRegistros();
            int totalRegistros = registros.Count;

            vm.Registros = registros;
            vm.TotalRegistros = totalRegistros;
            return vm;
        }

        private Cidade ConverterFormVM(CidadeFormVM vm)
        {
            Cidade registro = new Cidade();
            registro.IdCidade = vm.IdCidade;
            registro.NomeCidade = vm.NomeCidade;
            registro.UF = vm.UF;
            registro.FlagAtivo = (vm.FlagAtivo ? "S" : "N");

            return registro;
        }

        private CidadeFormVM ConverterFormVM(Cidade registro)
        {
            CidadeFormVM vm = new CidadeFormVM();
            vm.IdCidade = registro.IdCidade;
            vm.NomeCidade = registro.NomeCidade;
            vm.UF = registro.UF;
            vm.FlagAtivo = registro.FlagAtivo.Equals("S");

            return vm;
        }

        private CidadeFormVM ConstruirFormVMParaEdicao(int id)
        {
            Cidade registro = BuscarRegistroPorId(id);
            if (registro != null)
            {
                CidadeFormVM vm = ConverterFormVM(registro);
                vm.Edicao = true;
                vm.ItensUF = ListarItensUF();

                return vm;
            }

            return null;
            
        }

        private CidadeFormVM ConstruirFormVMParaNovo()
        {
            CidadeFormVM vm = new CidadeFormVM();
            vm.Edicao = false;
            vm.FlagAtivo = true;
            vm.ItensUF = ListarItensUF();

            return vm;
        }

        private List<SelectListItem> ListarItensUF()
        {
            List<SelectListItem> itens = new List<SelectListItem>();
            itens.Add(new SelectListItem { Text = "<Nenhum>", Value = ""});
            itens.Add(new SelectListItem { Text = "Acre", Value = "AC" });
            itens.Add(new SelectListItem { Text = "Alagoas", Value = "AL" });
            itens.Add(new SelectListItem { Text = "Amapá", Value = "AP" });
            itens.Add(new SelectListItem { Text = "Amazonas", Value = "AM" });
            itens.Add(new SelectListItem { Text = "Bahia", Value = "BA" });
            itens.Add(new SelectListItem { Text = "Ceará", Value = "CE" });
            itens.Add(new SelectListItem { Text = "Distrito Federal", Value = "DF" });
            itens.Add(new SelectListItem { Text = "Espírito Santo", Value = "ES" });
            itens.Add(new SelectListItem { Text = "Goiás", Value = "GO" });
            itens.Add(new SelectListItem { Text = "Maranhão", Value = "MA" });
            itens.Add(new SelectListItem { Text = "Mato Grosso", Value = "MT" });
            itens.Add(new SelectListItem { Text = "Mato Grosso do Sul", Value = "MS" });
            itens.Add(new SelectListItem { Text = "Minas Gerais", Value = "MG" });
            itens.Add(new SelectListItem { Text = "Pará", Value = "PA" });
            itens.Add(new SelectListItem { Text = "Paraíba", Value = "PB" });
            itens.Add(new SelectListItem { Text = "Paraná", Value = "PR" });
            itens.Add(new SelectListItem { Text = "Pernambuco", Value = "PE" });
            itens.Add(new SelectListItem { Text = "Piauí", Value = "PI" });
            itens.Add(new SelectListItem { Text = "Rio de Janeiro", Value = "RJ" });
            itens.Add(new SelectListItem { Text = "Rio Grande do Norte", Value = "RN" });
            itens.Add(new SelectListItem { Text = "Rio Grande do Sul", Value = "RS" });
            itens.Add(new SelectListItem { Text = "Rondônia", Value = "RO" });
            itens.Add(new SelectListItem { Text = "Roraima", Value = "RR" });
            itens.Add(new SelectListItem { Text = "Santa Catarina", Value = "SC" });
            itens.Add(new SelectListItem { Text = "São Paulo", Value = "SP" });
            itens.Add(new SelectListItem { Text = "Sergipe", Value = "SE" });
            itens.Add(new SelectListItem { Text = "Tocantins", Value = "TO" });

            return itens;
        }



        // ----------------------------------------------------------------------------------
        // Métodos auxiliares de acesso ao banco de dados.
        //
        // Os métodos abaixo se comunicam diretamente com o banco de dados.
        // ----------------------------------------------------------------------------------

        private Cidade BuscarRegistroPorId(int id)
        {
            Cidade registro = null;
            string sqlBuscar = "select * from cidade where IdCidade = " + id;
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();
            if (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }

            // Fecha a conexão
            gerenciadorConexao.Fechar();
            
            return registro;
        }






        private void InserirRegistro(Cidade cidade)
        {
            string sqlInserir = "insert into Cidade (IdCidade, NomeCidade, UF, Pais, FlagAtivo) values (seqCidade.NEXTVAL, ?, ?, ?, ?)";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
            
            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlInserir;

            OleDbParameter pNomeCidade = new OleDbParameter("NomeCidade", OleDbType.VarChar);
            pNomeCidade.Value = cidade.NomeCidade;
            comando.Parameters.Add(pNomeCidade);

            OleDbParameter pUF = new OleDbParameter("UF", OleDbType.VarChar);
            pUF.Value = cidade.UF;
            comando.Parameters.Add(pUF);

            OleDbParameter pPais = new OleDbParameter("Pais", OleDbType.VarChar);
            pPais.Value = "Brasil";  // A priori o sistema será apenas nacional, em futuras versões poderá dar suporte a outros países
            comando.Parameters.Add(pPais);

            OleDbParameter pFlagAtivo = new OleDbParameter("FlagAtivo", OleDbType.VarChar);
            pFlagAtivo.Value = cidade.FlagAtivo;
            comando.Parameters.Add(pFlagAtivo);

            // Insert
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private void AtualizarRegistro(Cidade cidade)
        {
            string sqlAtualizar = "update Cidade set NomeCidade = ?, UF = ?, FlagAtivo = ? where IdCidade = ?";
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
            
            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            OleDbParameter pNomeCidade = new OleDbParameter("NomeCidade", OleDbType.VarChar);
            pNomeCidade.Value = cidade.NomeCidade;
            comando.Parameters.Add(pNomeCidade);

            OleDbParameter pUF = new OleDbParameter("UF", OleDbType.VarChar);
            pUF.Value = cidade.UF;
            comando.Parameters.Add(pUF);

            OleDbParameter pFlagAtivo = new OleDbParameter("FlagAtivo", OleDbType.VarChar);
            pFlagAtivo.Value = cidade.FlagAtivo;
            comando.Parameters.Add(pFlagAtivo);

            OleDbParameter pIdCidade = new OleDbParameter("IdCidade", OleDbType.Integer);
            pIdCidade.Value = cidade.IdCidade;
            comando.Parameters.Add(pIdCidade);

            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private void DesativarRegistroPorId(int id)
        {
            string sqlAtualizar = "update CIDADE set flagAtivo = 'N' where idCidade = " + id;
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();
            
            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }

        private void AtivarRegistroPorId(int id)
        {
            string sqlAtualizar = "update CIDADE set flagAtivo = 'S' where idCidade = " + id;
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();

            // Abre a conexão
            gerenciadorConexao.Abrir();

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            // Update
            comando.ExecuteNonQuery();

            // Fecha a conexão
            gerenciadorConexao.Fechar();
        }


        private List<Cidade> ListarRegistros()
        {

            // Configura o comando
            GerenciadorConexao gerenciadorConexao = new GerenciadorConexao();
            String sqlConsulta = "select * from CIDADE";
            
            // Abre a conexão
            gerenciadorConexao.Abrir();


            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = gerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Cidade> cidades = new List<Cidade>();
            while (dr.Read())
            {
                Cidade cidade = ConverterDataReaderParaObj(dr);
                cidades.Add(cidade);
            }

            // Fecha a conexão
            gerenciadorConexao.Fechar();


            return cidades;

        }


        private Cidade ConverterDataReaderParaObj(OleDbDataReader dr)
        {
            Cidade registro = new Cidade();
            registro.IdCidade = Int32.Parse(dr["IdCidade"].ToString());
            registro.NomeCidade = dr["NomeCidade"].ToString();
            registro.Pais = dr["Pais"].ToString();
            registro.UF = dr["UF"].ToString();
            registro.FlagAtivo = dr["FlagAtivo"].ToString();

            return registro;
        }

    }
}
